/** @file    WoshRemoteWindow.cpp
 *  @author  Alessandro Polo
 *  @version $Id: WoshRemoteWindow.cpp 2618 2010-06-04 09:48:15Z alex $
 *  @brief
 * File containing methods for the wosh::application::WoshRemoteWindow class.
 * The header for this class can be found in WoshRemoteWindow.h, check that file
 * for class description.
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/
 
 #include "WoshRemoteWindow.h"
 #include "ui_WoshRemoteWindow.h"

 #include <QtGui>

 #include <core/WoshKernel.h>
 #include <core/Request.h>
 #include <core/Response.h>
 #include <core/Table.h>

 #include <core/WoshKernel.h>
 #include <core/DeviceManager.h>
 #include <core/SecurityManager.h>
 #include <core/FileSystem.h>
 #include <core/UserManager.h>
 #include <core/BusManager.h>
 #include <core/ThreadManager.h>
 #include <core/BundleManager.h>
 #include <core/NetworkManager.h>

 #include <framework/gui/GuiDialogs.h>

 #include <framework/gui/components/FormConsole.h>

 #include <framework/gui/bundles/services/FormBuildingManager.h>

 #include <framework/gui/FormContainer.h>
 #include <framework/gui/WidgetProperties.h>


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _OS_POSIX
# include <core/posix/desktop.h>
#endif
#ifdef _OS_WIN32
# include <core/win32/desktop.h>
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace wosh {
  namespace application {
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
WoshRemoteWindow* WoshRemoteWindow::instance = NULL;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS

WoshRemoteWindow::WoshRemoteWindow(QWidget *parent) : QMainWindow(parent)
 {
	this->m_ui = new Ui::WoshRemoteWindow();
	this->m_ui->setupUi(this);

	this->desktopNotifierBundle = NULL;
	this->trayIcon = NULL;
	this->menuTrayMenu = NULL;

	this->formBuildingManager = NULL;

	this->reallyExiting = false;

	Log.setContext("WoshRemoteWindow");
	Log.setLevel( LOG_VERBOSE );
	Log.setIndent( 1 );

	WoshRemoteWindow::instance = this;

	this->myUri.setKernelLocal();
	this->myUri.clearPathName();
	this->myUri.setName("WoshRemoteWindow");


	connect(this, SIGNAL(s_DesktopNotifier(int)), this, SLOT(response_DesktopNotifier(int)), Qt::QueuedConnection);
	connect(this, SIGNAL(s_showMessage(const QString&,const QString&,long,QSystemTrayIcon::MessageIcon)), this, SLOT(showMessage(const QString&,const QString&,long,QSystemTrayIcon::MessageIcon)), Qt::QueuedConnection);

	connect(this->m_ui->chkDesktopNotifier, SIGNAL(clicked()), this, SLOT(chkDesktopNotifier_clicked()));
	connect(this->m_ui->chkTraySettingsSmartMenu, SIGNAL(clicked()), this, SLOT(chkTraySettingsSmartMenu_clicked()));


	this->m_ui->styleCombo->addItems(QStyleFactory::keys());
	connect(this->m_ui->styleCombo, SIGNAL(activated(const QString &)), this, SLOT(on_styleCombo_activated(const QString &)));
	connect(this->m_ui->styleSheetCombo, SIGNAL(activated(const QString &)), this, SLOT(on_styleSheetCombo_activated(const QString &)));

	connect(this->m_ui->wWoshBrowser, SIGNAL(request_create_GUI(const string&,const string&,const URI&,const QStringList&)),
			this, SLOT(create_GUI(const string&,const string&,const URI&,const QStringList&)) );
	this->m_ui->wWoshBrowser->refreshAll();

	this->m_ui->chkDesktopNotifier->setChecked(true);
	this->m_ui->wFormDesktopNotifier->setTargetURI( GuiUtilities::getSessionInfo().getCurrentKernel() + ":Bundles/" _DesktopNotifier_NAME );
	this->m_ui->wFormDesktopNotifier->refreshAll();

 }

WoshRemoteWindow::~WoshRemoteWindow()
 {
	writeSettings();

	this->trayIcon->hide();
	delete this->trayIcon; this->trayIcon = NULL;

	delete this->m_ui; this->m_ui = NULL;

	WoshRemoteWindow::instance = NULL;
 }

void WoshRemoteWindow::init()
 {
	BusCore.setMessageHandler(this);
	WRESULT bus_core_connected = BusCore.connect( _Bus_Core );
	(void)bus_core_connected;

	// setup and connect menus
	createMenus();
	// setup tray icon stuff
	createTrayIcon();
	// setup status bar fields
	configureStatusBar();

	refreshInfo();
	readSettings();
	
 }

void WoshRemoteWindow::quitWosh() {
	this->reallyExiting = true;
	QApplication::quit();
 }

//////////////////////////////////////////////////////////////////////////////////////////////// CONSTRUCTORS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::refreshInfo()
 {
	if ( GuiUtilities::getSessionInfo().getCurrentKernel() == WoshKernel::getKernelName() ) {
		setWindowTitle( QString("%1 v%2/%3.%4  - OpenSmartHome.com").arg(_APPLICATION_WOSH_REMOTE_NAME)
							.arg(_APPLICATION_WOSH_REMOTE_VERSION).arg(_WOSH_VER_MAJOR).arg(_WOSH_VER_MINOR) );
		Log(LOG_INFO, ":changeCurrentKernelUser() : Switching to Local Kernel [%s] as %s..", GuiUtilities::getSessionInfo().getCurrentKernel().c_str(), GuiUtilities::getSessionInfo().getUserName().c_str() );
	 }
	else {
		setWindowTitle( QString("%1@%2 - %3 v%4/%5.%6")
							.arg(GuiUtilities::getSessionInfo().getUserName().c_str()).arg(GuiUtilities::getSessionInfo().getCurrentKernel().c_str()).arg(_APPLICATION_WOSH_REMOTE_NAME)
							.arg(_APPLICATION_WOSH_REMOTE_VERSION).arg(_WOSH_VER_MAJOR).arg(_WOSH_VER_MINOR) );
		Log(LOG_INFO, ":changeCurrentKernelUser() : Switching to [%s] as %s..", GuiUtilities::getSessionInfo().getCurrentKernel().c_str(), GuiUtilities::getSessionInfo().getUserName().c_str() );
	 }

	this->statusBar()->showMessage(tr("Hi %1, Welcome to %2 version %3").arg(GuiUtilities::getSessionInfo().getUserName().c_str())
																		.arg(_APPLICATION_WOSH_REMOTE_NAME)
																		.arg(_APPLICATION_WOSH_REMOTE_VERSION), 5000);

	updateDynamicMenus();
	updateStatusBar();
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////// WORKSPACE

void WoshRemoteWindow::create_GUI( const string& name, const string& type, const URI& uri, const QStringList& interfaces )
 {
	Log(LOG_VERBOSE, ":create_GUI() : GUI for %s [%s]#%i {%s}", name.c_str(), type.c_str(), interfaces.size(), uri.toString().c_str() );
	IWidget* guiWidget = GuiUtilities::create_GUI( name, type, uri, interfaces );
	if ( guiWidget == NULL ) {
		QMessageBox::information(0, this->windowTitle(), QString("Sorry, Can't allocate GUI for '%1' [%2]").arg(type.c_str()).arg(interfaces.join(";")) );
		return;
	 }
	guiWidget->refreshAll();
	QWidget* asWidget = dynamic_cast<QWidget*>(guiWidget);
	if ( asWidget == NULL )
		return;
	asWidget->show();
 }

/////////////////////////////////////////////////////////////////////////////////////////////////// WORKSPACE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////// MENU HANLDERS

void WoshRemoteWindow::menu_StaticItem_triggered( QAction* action )
 {
	if ( action == NULL ) return;

	// WOSH
	else if ( action == this->m_ui->actionTray_Building ) {
		if ( this->formBuildingManager == NULL ) {
			this->formBuildingManager = new FormBuildingManager();
			this->formBuildingManager->setTargetURI( URI("wosh1:Building") );
			//this->formBuildingManager
			connect(this->formBuildingManager, SIGNAL(request_create_GUI(const string&,const string&,const URI&,const QStringList&)),
					this, SLOT(create_GUI(const string&,const string&,const URI&,const QStringList&)) );
			this->formBuildingManager->refreshAll();
		 }
		this->formBuildingManager->show();
	 }
	else if ( action == this->m_ui->actionWOSH_Terminal ) {
		FormConsole* cF = new FormConsole();
		cF->show();
	 }
	else if ( action == this->m_ui->actionWOSH_Quit ) {
		quitWosh();
	 }

	// Bundles
	else if ( action == this->m_ui->actionBundles_CreateGUI ) {
		DialogCreateGui* dCgui = new DialogCreateGui(this);
		if ( dCgui->exec() == QDialog::Accepted ) {
			create_GUI(dCgui->getName(), dCgui->getType(), dCgui->getURI(), dCgui->getInterfaces() );
		 }
	 }

	// Network
	else if ( action == this->m_ui->actionNetwork_Refresh ) {
		this->m_ui->menuNetwork_Hosts->refreshAll();
		this->m_ui->menuNetwork_Protocols->refreshAll();
		this->m_ui->menuNetwork_Channels->refreshAll();
	 }

	// Tools
	else if ( action == this->m_ui->actionTools_PropertiesEditor ) {
		WidgetPropertiesEditor* wpE = new WidgetPropertiesEditor();
		wpE->show();
	 }

	// HELP menu
	else if ( action == this->m_ui->actionHelp_Documentation ) {
		QDesktopServices::openUrl( QUrl("http://wosh.sourceforge.net/doc/") );
	 }
	else if ( action == this->m_ui->actionHelp_WOSH_Online ) {
		QDesktopServices::openUrl( QUrl("https://sourceforge.net/projects/wosh/") );
	 }
	else if ( action == this->m_ui->actionHelp_AlessandroPoloOnline ) {
		QDesktopServices::openUrl( QUrl("http://www.alessandropolo.name") );
	 }
	else if ( action == this->m_ui->actionHelp_OpenSmartHome_com ) {
		QDesktopServices::openUrl( QUrl("http://www.opensmarthome.com") );
	 }
	else if ( action == this->m_ui->actionHelp_CheckforUpdates ) {
		///@todo CheckforUpdates
		QMessageBox::warning(this, this->windowTitle(), tr("Feature NOT Implemented yet.") );
	 }
	else if ( action == this->m_ui->actionHelp_AboutWOSHRemote ) {
		QMessageBox::information(this, this->windowTitle(), "<h1>" _APPLICATION_WOSH_REMOTE_NAME "</h1>"
									"<h3>version " _APPLICATION_WOSH_REMOTE_VERSION " - December 2009</h3>"
									"<h2>Remote Controller for WOSH Network</h2>"
									"<p>Refer to <a href='https://sourceforge.net/projects/wosh/'>https://sourceforge.net/projects/wosh/</a>.</p>"
									"<p>An open source software by <a href='mailto:contact@alessandropolo.name'>Alessandro Polo</a>.</p>" );
	 }
	else if ( action == this->m_ui->actionHelp_AboutWOSH ) {
		GuiUtilities::aboutWOSH(this);
	 }
	else if ( action == this->m_ui->actionHelp_AboutQT ) {
		QMessageBox::aboutQt(this);
	 }

 }

void WoshRemoteWindow::menu_CreateGUI_triggeredItem( WidgetQMenuItem * actionItem ) { // CHANGE TO REMOTEOBJECT !!
	if ( actionItem == NULL ) return;

	create_GUI( actionItem->getRemoteName(), // CHANGE TO REMOTEOBJECT !!
				actionItem->getRemoteType(),
				actionItem->getRemoteURI(),
				actionItem->getInterfaces() ); // CHANGE TO DATALIST in REMOTEOBJECT !!
 }

void WoshRemoteWindow::menuWOSH_Kernel_triggeredItem( WidgetQMenuItem * actionItem ) {
	if ( actionItem == NULL ) return;
	GuiUtilities::getSessionInfo().transactionBeginWrite();
	GuiUtilities::getSessionInfo().getCurrentLocation().setKernelName( actionItem->text().toLatin1().data() );
	GuiUtilities::getSessionInfo().transactionEnd();
	refreshInfo();
 }

/////////////////////////////////////////////////////////////////////////////////////////////// MENU HANLDERS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// CREATE/UPDATE MENU

void WoshRemoteWindow::createMenus() {
	Log(LOG_VERBOSE, ":createMenus() : Setting up.." );

	// MENU Modules
	connect(this->m_ui->menu_Modules, SIGNAL( triggeredItem( WidgetQMenuItem* ) ), this, SLOT(menu_CreateGUI_triggeredItem( WidgetQMenuItem* )));

	// MENU Bundles
	connect(this->m_ui->menu_Bundles, SIGNAL( triggeredItem( WidgetQMenuItem* ) ), this, SLOT(menu_CreateGUI_triggeredItem( WidgetQMenuItem* )));

	// MENU Devices
	connect(this->m_ui->menu_Devices, SIGNAL( triggeredItem( WidgetQMenuItem* ) ), this, SLOT(menu_CreateGUI_triggeredItem( WidgetQMenuItem* )));

	// MENU Communication
	connect(this->m_ui->menu_Communication, SIGNAL( triggeredItem( WidgetQMenuItem* ) ), this, SLOT(menu_CreateGUI_triggeredItem( WidgetQMenuItem* )));

	// Static items from MENUS
	connect(this->m_ui->menu_WOSH, SIGNAL( triggered( QAction* ) ), this, SLOT(menu_StaticItem_triggered( QAction* )));
	connect(this->m_ui->menu_Devices, SIGNAL( triggered( QAction* ) ), this, SLOT(menu_StaticItem_triggered( QAction* )));
	connect(this->m_ui->menu_Network, SIGNAL( triggered( QAction* ) ), this, SLOT(menu_StaticItem_triggered( QAction* )));
	connect(this->m_ui->menu_Tools, SIGNAL( triggered( QAction* ) ), this, SLOT(menu_StaticItem_triggered( QAction* )));
	connect(this->m_ui->menu_Help, SIGNAL( triggered( QAction* ) ), this, SLOT(menu_StaticItem_triggered( QAction* )));
	connect(this->menuTrayMenu, SIGNAL( triggered( QAction* ) ), this, SLOT(menu_StaticItem_triggered( QAction* )));

 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::updateDynamicMenus() {
	Log(LOG_VERBOSE, ":updateDynamicMenus() : Updating Menus [%s]..", GuiUtilities::getSessionInfo().getCurrentKernel().c_str() );

	this->m_ui->menu_Modules->getTargetURI().setKernelName(GuiUtilities::getSessionInfo().getCurrentKernel());
	this->m_ui->menu_Modules->getTargetURI().setName("");
	this->m_ui->menu_Modules->setDefaultType(_WoshModule_TYPE);
	this->m_ui->menu_Modules->refreshAll();

	this->m_ui->menu_Bundles->getTargetURI().setKernelName(GuiUtilities::getSessionInfo().getCurrentKernel());
	this->m_ui->menu_Bundles->getTargetURI().setName("Bundles");
	this->m_ui->menu_Bundles->setDefaultType(_Bundle_TYPE);
	this->m_ui->menu_Bundles->refreshAll();

	this->m_ui->menu_Devices->getTargetURI().setKernelName("*");
	this->m_ui->menu_Devices->getTargetURI().setName("Devices");
	this->m_ui->menu_Devices->setDefaultType(_Device_TYPE);
	this->m_ui->menu_Devices->refreshAll();

	this->m_ui->menu_Communication->getTargetURI().setKernelName("*");
	this->m_ui->menu_Communication->getTargetURI().setName("Communication");
	this->m_ui->menu_Communication->setDefaultType(_Communicator_TYPE);
	this->m_ui->menu_Communication->refreshAll();

	this->m_ui->menuNetwork_Protocols->getTargetURI().setKernelName(GuiUtilities::getSessionInfo().getCurrentKernel());
	this->m_ui->menuNetwork_Protocols->getTargetURI().setName("Network");
	this->m_ui->menuNetwork_Protocols->setRequestMethod(_NetworkManager_METHOD_Protocols_list);
	this->m_ui->menuNetwork_Protocols->refreshAll();

	this->m_ui->menuNetwork_Channels->getTargetURI().setKernelName(GuiUtilities::getSessionInfo().getCurrentKernel());
	this->m_ui->menuNetwork_Channels->getTargetURI().setName("Network");
	this->m_ui->menuNetwork_Channels->setRequestMethod(_NetworkManager_METHOD_Channels_list);
	this->m_ui->menuNetwork_Channels->refreshAll();

	this->m_ui->menuNetwork_Hosts->getTargetURI().setKernelName(GuiUtilities::getSessionInfo().getCurrentKernel());
	this->m_ui->menuNetwork_Hosts->getTargetURI().setName("Network");
	this->m_ui->menuNetwork_Hosts->setDefaultType(WoshHost::className());
	this->m_ui->menuNetwork_Hosts->setForceType(true);
	this->m_ui->menuNetwork_Hosts->setRequestMethod(_NetworkManager_METHOD_Hosts_list);
	this->m_ui->menuNetwork_Hosts->refreshAll();
 }

////////////////////////////////////////////////////////////////////////////////////////// CREATE/UPDATE MENU
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////// TRAY ICON METHODS

void WoshRemoteWindow::createTrayIcon() {
	Log(LOG_VERBOSE, ":createTrayIcon() : Setting up.." );

	this->menuTrayMenu = new QMenu(this);
	this->menuTrayMenu->addAction( this->m_ui->actionWOSH_Quit );
	this->menuTrayMenu->addSeparator();
	this->menuTrayMenu->addAction( this->m_ui->actionTray_Building );
	this->menuTrayMenu->addSeparator();

	this->trayIcon = new QSystemTrayIcon(this);
	this->trayIcon->setContextMenu(this->menuTrayMenu);
	this->trayIcon->setIcon(this->windowIcon());
	this->trayIcon->setToolTip(this->windowTitle());
	connect(this->trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
	this->trayIcon->show();
 }

void WoshRemoteWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) {
	if ( reason != QSystemTrayIcon::DoubleClick ) return;
	if ( this->isVisible() )
		this->hide();
	else {
		this->show();
		///@todo force window on top
	 }
 }

/////////////////////////////////////////////////////////////////////////////////////////// TRAY ICON METHODS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// STATUS BAR METHODS

void WoshRemoteWindow::configureStatusBar() {
	Log(LOG_VERBOSE, ":configureStatusBar() : Setting up.." );

	this->statusUserAtKernelLbl = new QLabel();
//	this->statusUserAtKernelLbl->setFrameShape(QFrame::StyledPanel);

	QLabel* statusEmpty = new QLabel(this->statusBar());
//	statusEmpty->setFrameShape(QFrame::NoFrame);
//	statusEmpty->setFrameShadow(QFrame::Plain);
//	statusEmpty->setLineWidth(0);

	this->statusBar()->addWidget(statusEmpty, 1);
	this->statusBar()->addWidget(this->statusUserAtKernelLbl, 0);

	updateStatusBar();
 }

void WoshRemoteWindow::updateStatusBar() {
	this->statusUserAtKernelLbl->setText( QString("%1@%2").arg(GuiUtilities::getSessionInfo().getUserName().c_str()).arg(GuiUtilities::getSessionInfo().getCurrentKernel().c_str()) );
 }

////////////////////////////////////////////////////////////////////////////////////////// STATUS BAR METHODS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////// SIGNAL->EVENT

void WoshRemoteWindow::showMessage( const QString& title, const QString& message, long timeout, QSystemTrayIcon::MessageIcon icon ) {
	this->statusBar()->showMessage(tr("%1: %2").arg(title).arg(message), timeout);

	if ( this->trayIcon == NULL )
		return;
	if ( !this->m_ui->chkTraySettingsShowMessages->isChecked() )
		return;
	this->trayIcon->showMessage(title, message, icon, timeout);
 }

void WoshRemoteWindow::response_DesktopNotifier( int state ) {
	if ( state )
		this->setStatusTip( tr("DesktopNotifier has been started.") );
	else
		this->setStatusTip( tr("DesktopNotifier has been stopped.") );

	this->m_ui->chkDesktopNotifier->setChecked( state );
	this->m_ui->wFormDesktopNotifier->setEnabled( state );
 }

/////////////////////////////////////////////////////////////////////////////////////////////// SIGNAL->EVENT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////// SETTINGS

void WoshRemoteWindow::readSettings() {
	Log(LOG_VERBOSE, ":readSettings() : Reading.." );
	QSettings settings("OpenSmartHome.com", _APPLICATION_WOSH_REMOTE_NAME);

	int winstate = settings.value("state", (int)Qt::WindowActive).toInt();
	this->setWindowState( (Qt::WindowState)winstate );

	QPoint pos = settings.value("pos", QPoint(50, 50)).toPoint();
	move(pos);

	QSize size = settings.value("size", QSize(740, 560)).toSize();
	resize(size);

	QString language = settings.value("language", QLocale::system().name() ).toString();
	loadLanguage(language);

	QString styleName = settings.value("style", "Plastique").toString();
	QString styleSheet = settings.value("styleSheet", "Coffee").toString();
	this->m_ui->styleCombo->setCurrentIndex(this->m_ui->styleCombo->findText(styleName));
	this->m_ui->styleSheetCombo->setCurrentIndex(this->m_ui->styleSheetCombo->findText(styleSheet));

	qApp->setStyle(styleName);
	loadStyleSheet(styleSheet);
 }

void WoshRemoteWindow::writeSettings() {
	Log(LOG_VERBOSE, ":writeSettings() : Writing.." );
	QSettings settings("OpenSmartHome.com", _APPLICATION_WOSH_REMOTE_NAME);

	settings.setValue("state", (int)this->windowState() );
	if ( this->windowState() != Qt::WindowMaximized && this->windowState() != Qt::WindowFullScreen ) {
		settings.setValue("pos", pos());
		settings.setValue("size", size());
	 }

	settings.setValue("style", qApp->style()->objectName() );
	settings.setValue("styleSheet", qApp->styleSheet() );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////// SETTINGS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::changeEvent(QEvent *e) {
	QMainWindow::changeEvent(e);
	switch (e->type()) {
		case QEvent::LanguageChange:
			m_ui->retranslateUi(this);
			refreshInfo(); // refresh title
			break;
		default:
			break;
	 }
 }

void WoshRemoteWindow::closeEvent(QCloseEvent *event) {
	if ( this->reallyExiting ) return;
	if (trayIcon->isVisible()) {
		//The program will keep running in the system tray.
		hide();
		event->ignore();
	 }
 }
 
void WoshRemoteWindow::setVisible(bool visible) {
//	this->minimizeAction->setEnabled(visible);
//	this->maximizeAction->setEnabled( !isMaximized() );
//	this->m_ui->actionTray_Restore->setEnabled(isMaximized() || !visible);
	QWidget::setVisible(visible);
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::loadStyleSheet(const QString &sheetName) {
	QFile file(":/qss/" + sheetName.toLower() + ".qss");
	file.open(QFile::ReadOnly);
	QString styleSheet = QLatin1String(file.readAll());
	qApp->setStyleSheet(styleSheet);
 }

void WoshRemoteWindow::loadLanguage(const QString& language) {
	if ( language.size() == 0 ) return;

	QTranslator* qtTranslator = new QTranslator();
	QString trQt = "qt_" + language;
	bool loadedQt = qtTranslator->load(trQt, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
	if ( loadedQt )
		qApp->installTranslator(qtTranslator);
//	else
//		QMessageBox::critical(this, this->windowTitle(), QString("Error occurred while loading Translation file [%1].").arg(trQt) );

	QTranslator* woshWidgetTranslator = new QTranslator();
	QString trWw = ":/translations/widgets."+language+".qm";
	bool loadedWw = woshWidgetTranslator->load( trWw );
	if ( loadedWw )
		qApp->installTranslator(woshWidgetTranslator);
	else
		QMessageBox::critical(this, this->windowTitle(), QString("Error occurred while loading Translation file [%1].").arg(trWw) );

	QTranslator* myappTranslator = new QTranslator();
	QString trMy = ":/translations/"+language+".qm";
	bool loadedMy = myappTranslator->load( trMy );
	if ( loadedMy )
		qApp->installTranslator(myappTranslator);
	else
		QMessageBox::critical(this, this->windowTitle(), QString("Error occurred while loading Translation file [%1].").arg(trMy) );
 }

void WoshRemoteWindow::on_styleCombo_activated(const QString &styleName) {
	qApp->setStyle(styleName);
 }

void WoshRemoteWindow::on_styleSheetCombo_activated(const QString &sheetName) {
	loadStyleSheet(sheetName);
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::chkDesktopNotifier_clicked() {
	Request* request = NULL;
	if ( this->m_ui->chkDesktopNotifier->isChecked() )
		request = new Request( _Bundle_METHOD_Start );
	else
		request = new Request( _Bundle_METHOD_Stop );
	if ( request == NULL ) return;

	Message* message = new Message(request);
	message->setSource( this->myUri );
	message->getDestination().setKernelLocal();
	message->getDestination().setPath("Bundles");
	message->getDestination().setName(_DesktopNotifier_NAME);
	message->setDestinationBus( _Bus_Core );
	GuiUtilities::getSessionInfo().signMessage(message);
	BusCore.postMessage(message);
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::chkTraySettingsSmartMenu_clicked() {
	this->m_ui->grpTraySettingsSmartMenu->setEnabled(this->m_ui->chkTraySettingsSmartMenu->isChecked());
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WoshRemoteWindow::busMessage( const Message& message, const Bus* ) {
	if ( message.getContent()->isResponse() ) {
		const wosh::Response* response = message.getContent()->asResponse();

		if ( message.getSource().isKernelLocal() && message.getSource().getName() == _DesktopNotifier_NAME ) {
			short enabled = 2;
			if ( response->getMethod() == _Bundle_METHOD_Start )
				enabled = 1;
			else if ( response->getMethod() == _Bundle_METHOD_Stop )
				enabled = 0;
			if ( enabled == 2 ) return;

			emit s_DesktopNotifier(enabled);
		 }

		if ( !URI::pregMatch( this->myUri, message.getDestination() ) )
			return;

		return;
	 }

	else if ( message.getContent()->isFact() ) {
		if (message.getSource().getName() == "Network" ) {
			const wosh::Fact* fact = message.getContent()->asFact();
			if ( fact->getEvent() == _NetworkManager_EVENT_WoshHostAdded ) {
				//QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::MessageIcon::Information;
				QString str = tr("New WOSH Host '%1' found");
				if ( fact->hasData() && fact->getDataClassName() == Variant::className() ) {
					const wosh::Variant* data = dynamic_cast<const wosh::Variant*>(fact->getData());
					str = str.arg(data->toString().c_str());
				 }
				else if ( fact->hasData() && fact->getDataClassName() == WoshHost::className() ) {
					const wosh::WoshHost* host = dynamic_cast<const wosh::WoshHost*>(fact->getData());
					str = str.arg(host->getName().c_str());
				 }
				else
					str = str.arg("UNKNOWN");
				emit s_showMessage("Network", str, 5, QSystemTrayIcon::Information);
			 }
			else if ( fact->getEvent() == _NetworkManager_EVENT_WoshHostConnected ) {
				QString str = tr("WOSH Host '%1' Connected");
				if ( fact->hasData() && fact->getDataClassName() == Variant::className() ) {
					const wosh::Variant* data= dynamic_cast<const wosh::Variant*>(fact->getData());
					str = str.arg(data->toString().c_str());
				 }
				emit s_showMessage("Network", str, 5, QSystemTrayIcon::Information);
			 }
			else if ( fact->getEvent() == _NetworkManager_EVENT_WoshHostDisconnected ) {
				QString str = tr("WOSH Host '%1' Disonnected");
				if ( fact->hasData() && fact->getDataClassName() == Variant::className() ) {
					const wosh::Variant* data= dynamic_cast<const wosh::Variant*>(fact->getData());
					str = str.arg(data->toString().c_str());
				 }
				emit s_showMessage("Network", str, 15, QSystemTrayIcon::Warning);
			 }
		 }
	 }

 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

  }; // namespace application
}; // namespace wosh
